#include "CLeanServer.h"
#include "CTableManager.h"
#include "CTableBase.h"
#include "CTableConfigure.h"
#include "CLogDatabase.h"
#include "CppSQLite3.h"
#include <chrono>
#include <iostream>
#include <string>

CLeanServer::CLeanServer()
	: m_tableManager(nullptr)
	, m_stopRequested(false)
	, m_isRunning(false)
{
}

CLeanServer::~CLeanServer()
{
	// 确保在析构时停止定时清理服务
	StopScheduledCleanup();
}

int CLeanServer::Initialize(CTableManager* tableManager)
{
	if (!tableManager) {
		return -1;
	}
	
	m_tableManager = tableManager;
	return 0;
}

int CLeanServer::CleanExpiredLogs()
{
	if (!m_tableManager) {
		return -1;
	}

	int totalCleaned = 0;
	
	// 遍历所有表
	for (const auto& tablePair : m_tableManager->m_tableMap) {
		const std::string& tableName = tablePair.first;
		const CTableBasePtr& table = tablePair.second;
		
		if (!table) {
			continue;
		}
		
		// 检查表类型是否为需要清理的类型
		if (!IsTableTypeForCleanup(table->getTableType())) {
			continue;
		}
		
		// 获取表的日志数据库
		CLogDatabase* logDatabase = table->getLogDatabase().get();
		if (!logDatabase) {
			continue;
		}
		
		boost::lock_guard<CLogDatabase> lock(*logDatabase);

		int cleaned = CleanTableExpiredLogs(tableName, logDatabase, table.get());
		if (cleaned > 0) {
			totalCleaned += cleaned;
			std::cout << "Cleaned " << cleaned << " expired records from table: " << tableName << std::endl;
		}
	}
	
	return totalCleaned;
}

bool CLeanServer::IsTableTypeForCleanup(int tableType) const
{
	// 只清理这三种类型的表
	return (tableType == TableTypeAppend || 
			tableType == TableTypeUpAppend || 
			tableType == TableTypeAppendWithCounter);
}

int CLeanServer::CleanTableExpiredLogs(const std::string& tableName, CLogDatabase* logDatabase, CTableBase* table)
{
	if (!logDatabase || !table) {
		return -1;
	}
	
	CppSQLite3DB* db = logDatabase->getDatabaseConnection();
	if (!db) {
		return -1;
	}
	
	try {
		// 检查表是否存在
		if (!db->tableExists(tableName.c_str())) {
			std::cerr << "Table " << tableName << " does not exist" << std::endl;
			return -1;
		}
		
		// 获取当前时间戳
		uint64_t currentTime = GetCurrentTimestamp();
		
		// 获取表的当前上传游标
		uint64_t uploadedCursor = table->getUploadedCursor();
		
		// 计算清理时间点
		uint64_t uploadedCutoffTime = currentTime - UPLOADED_RETENTION_DAYS;
		uint64_t unuploadedCutoffTime = currentTime - UNUPLOADED_RETENTION_DAYS;
		
		// 使用 ltm 字段作为时间判断，通过游标判断是否上传过
		// 为了性能考虑，分批处理，每次筛选1000条记录
		
		int totalDeletedRows = 0;
		const int BATCH_SIZE = 1000; // 每批处理1000条记录
		
		// 先通过时间筛选出一批数据，再通过ID判断是否被上传


		totalDeletedRows += CleanExpiredRecordsInBatches(db, tableName, uploadedCutoffTime, 
														unuploadedCutoffTime, uploadedCursor, BATCH_SIZE);
		

		return totalDeletedRows;
		
	} catch (CppSQLite3Exception& e) {
		//std::cerr << "Error cleaning expired logs from table " << tableName 
		//		  << ": " << e.errorMessage() << std::endl;
		return -1;
	}
}

int CLeanServer::CleanExpiredRecordsInBatches(CppSQLite3DB* db, const std::string& tableName, 
											  uint64_t uploadedCutoffTime, uint64_t unuploadedCutoffTime, 
											  uint64_t uploadedCursor, int batchSize)
{
	if (!db) {
		return -1;
	}
	
	int totalDeletedRows = 0;
	
	try {
		// 通过时间筛选出一批要清理的记录（限制数量为batchSize）
		// 使用更宽松的时间条件，确保不会遗漏需要清理的记录
		uint64_t timeCutoff = std::max(uploadedCutoffTime, unuploadedCutoffTime);
		std::string selectSql = "SELECT id, ltm FROM " + tableName + 
							   " WHERE ltm < " + std::to_string(timeCutoff) + 
							   " LIMIT " + std::to_string(batchSize);
		
		CppSQLite3Query query = db->execQuery(selectSql.c_str());
		
		// 收集要删除的记录ID，并根据时间判断是否应该删除
		std::vector<int> recordIdsToDelete;
		while (!query.eof()) {
			int recordId = query.getIntField("id");
			uint64_t recordTime = query.getInt64Field("ltm");
			
			// 根据记录时间和上传游标判断是否应该删除
			bool shouldDelete = false;
			
			// 通过记录ID与上传游标比较来判断是否已上传
			if (recordId <= uploadedCursor) {
				// 记录ID小于等于上传游标，说明这条记录已经被上传过
				// 对于已上传的记录，超过5天就删除
				if (recordTime < uploadedCutoffTime) {
					shouldDelete = true;
				}
			} else {
				// 记录ID大于上传游标，说明这条记录还没有被上传过
				// 对于未上传的记录，超过30天就删除
				if (recordTime < unuploadedCutoffTime) {
					shouldDelete = true;
				}
			}
			
			if (shouldDelete) {
				recordIdsToDelete.push_back(recordId);
			}
			
			query.nextRow();
		}
		query.finalize();
		
		// 如果没有找到需要删除的记录，直接返回
		if (recordIdsToDelete.empty()) {
			return 0;
		}
		
		// 通过ID删除记录
		if (!recordIdsToDelete.empty()) {
			// 构建IN子句
			std::stringstream deleteSql;
			deleteSql << "DELETE FROM " + tableName + " WHERE id IN (";
			
			for (size_t i = 0; i < recordIdsToDelete.size(); ++i) {
				if (i > 0) {
					deleteSql << ", ";
				}
				deleteSql << recordIdsToDelete[i];
			}
			deleteSql << ")";
			
			// 执行删除
			int deletedRows = db->execDML(deleteSql.str().c_str());
			totalDeletedRows += deletedRows;
			
			std::cout << "Cleaned batch of " << deletedRows << " expired records from table: " << tableName << std::endl;
		}
		
		if (totalDeletedRows > 0) {
			std::cout << "Total cleaned " << totalDeletedRows << " expired records from table: " << tableName << std::endl;
		}
		
		return totalDeletedRows;
		
	} catch (CppSQLite3Exception& e) {
		//std::cerr << "Error cleaning expired records in batches from table " + tableName 
		//		  << ": " << e.errorMessage() << std::endl;
		return -1;
	}
}

uint64_t CLeanServer::GetCurrentTimestamp() const
{
	// 获取当前时间戳（秒）
	auto now = std::chrono::system_clock::now();
	auto duration = now.time_since_epoch();
	return std::chrono::duration_cast<std::chrono::seconds>(duration).count();
}

int CLeanServer::StartScheduledCleanup()
{
	if (m_isRunning) {
		std::cout << "Scheduled cleanup is already running" << std::endl;
		return 0;
	}
	
	if (!m_tableManager) {
		std::cerr << "Table manager not initialized, cannot start scheduled cleanup" << std::endl;
		return -1;
	}
	
	// 重置停止标志
	m_stopRequested = false;
	m_isRunning = true;
	
	// 启动定时清理线程
	m_cleanupThread = std::thread(&CLeanServer::ScheduledCleanupLoop, this);
	
	std::cout << "Scheduled cleanup service started successfully" << std::endl;
	std::cout << "Cleanup interval: " << CLEANUP_INTERVAL_MINUTES << " minute(s)" << std::endl;
	
	return 0;
}

void CLeanServer::StopScheduledCleanup()
{
	if (!m_isRunning) {
		return;
	}
	
	std::cout << "Stopping scheduled cleanup service..." << std::endl;
	
	// 设置停止标志
	m_stopRequested = true;
	
	// 等待线程结束
	if (m_cleanupThread.joinable()) {
		m_cleanupThread.join();
	}
	
	m_isRunning = false;
	std::cout << "Scheduled cleanup service stopped" << std::endl;
}

bool CLeanServer::IsScheduledCleanupRunning() const
{
	return m_isRunning;
}

void CLeanServer::ScheduledCleanupLoop()
{
	std::cout << "Scheduled cleanup loop started" << std::endl;
	
    try
    {
        while (!m_stopRequested) {
            try {
                // 执行清理任务
                std::cout << "Executing scheduled cleanup at " << GetCurrentTimestamp() << std::endl;
                
                int cleanedCount = CleanExpiredLogs();
                if (cleanedCount >= 0) {
                    std::cout << "Scheduled cleanup completed, cleaned " << cleanedCount << " expired records" << std::endl;
                } else {
                    std::cerr << "Scheduled cleanup failed with error code: " << cleanedCount << std::endl;
                }
                
            } catch (const std::exception& e) {
                std::cerr << "Exception in scheduled cleanup: " << e.what() << std::endl;
            }
            
            // 等待指定的时间间隔，同时检查停止请求
            auto startTime = std::chrono::steady_clock::now();
            auto interval = std::chrono::minutes(CLEANUP_INTERVAL_MINUTES);
            
            while (!m_stopRequested) {
                auto currentTime = std::chrono::steady_clock::now();
                auto elapsed = currentTime - startTime;
                
                if (elapsed >= interval) {
                    break; // 时间到了，执行下一次清理
                }
                
                // 每100毫秒检查一次停止请求，避免长时间等待
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
        }
    }
    catch(const std::exception& e){ }
    catch(...){}
    
	
	
	std::cout << "Scheduled cleanup loop ended" << std::endl;
}
